﻿/*
 * Cratos Tools - General
 * Cratos Data Access Interface declaration
 * 
 * Copyright (c) 2011-2012 Draco
 * 
 * This file is part of Cratos.
 * 
 * Cratos is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * Cratos is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Cratos.  If not, see <http://www.gnu.org/licenses/>.
 * 
 *       .==.        .==.
 *      //'^\\      //^'\\
 *     // ^ ^\(\__/)/^ ^^\\
 *    //^ ^^ ^/6  6\ ^^ ^ \\
 *   //^ ^^ ^/( .. )\^ ^ ^ \\
 *  // ^^ ^/\| V""V|/\^ ^ ^ \\
 * //^^/\/ /  '~~'  \ \/\^ ^ \\
 *  ------------------------------------
 *  HERE BE DRAGONS
 *  
 *  Johan Dercksen - johan@draco.co.za
 */
using System;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Common;
using System.Collections.Generic;

namespace Cratos.Tools.General
{
	/// <summary>
	/// Cratos Data Access Interface definition
	/// </summary>
	public interface ICratosDataAccess
	{
		#region Event declarations
		#endregion

		#region Property declarations
		/// <summary>
		/// Database Type
		/// </summary>
		CratosDatabaseType DatabaseType { get; set; }

		/// <summary>
		/// Command Type
		/// </summary>
		DOCratosActionType DBActionType { get; set; }

		/// <summary>
		/// Command Text
		/// </summary>
		string DBActionText { get; set; }

		/// <summary>
		/// Command Timeout
		/// </summary>
		int CommandTimeout { get; set; }

		/// <summary>
		/// Connection String
		/// </summary>
		string ConnectionString { get; set; }

		/// <summary>
		/// Connection Object
		/// </summary>
		IDbConnection Connection { get; set; }

		/// <summary>
		/// Command Object
		/// </summary>
		DbCommand Command { get; }

		/// <summary>
		/// Use Transactional support
		/// </summary>
		bool UseTransaction { get; set; }

		/// <summary>
		/// Data Reader
		/// </summary>
		IDataReader DataReader { get; }

		/// <summary>
		/// Reader contains data
		/// </summary>
		bool ReaderHasRows { get; }

		/// <summary>
		/// Database Result
		/// </summary>
		CratosDatabaseResult Result { get; }
		#endregion

		#region Method declarations
		/// <summary>
		/// Database Connect
		/// </summary>
		/// <remarks>
		/// This method makes use of the connection properties to open a connection to
		/// the database required.
		/// </remarks>
		/// <returns>
		/// A boolean value is returned indicating the success of the method
		/// </returns>
		bool Connect();

		/// <summary>
		/// Database Disconnect
		/// </summary>
		/// <remarks>
		/// This method closes a previously opened connection.
		/// </remarks>
		/// <returns>
		/// A boolean value is returned indicating the success of the method
		/// </returns>
		void Disconnect();

		/// <summary>
		/// Setup Connection
		/// </summary>
		/// <remarks>
		/// This method is used to setup the connection objects appropriately
		/// </remarks>
		void SetupConnection();

		/// <summary>
		/// Setup Command
		/// </summary>
		void SetupCommand();

		/// <summary>
		/// Execute Non Query
		/// </summary>
		/// <remarks>
		/// This method is used to execute a stored procedure where no results is expected.
		/// </remarks>
		void ExecuteNonQuery();

		/// <summary>
		/// Execute the query and return a Data Set
		/// </summary>
		/// <remarks>
		/// This method is used to execute the stored procedure and return the result as a 
		/// dataset to the calling method.
		/// </remarks>
		/// <returns>
		/// This method returns a dataset with the relevant data
		/// </returns>
		DataSet ExecuteDataSet();

		/// <summary>
		/// Execute the query and return an object
		/// </summary>
		/// <remarks>
		/// This method is used to execute the stored procedure and return the value of the 
		/// first row, the first column to the calling method.
		/// </remarks>
		/// <returns>
		/// This method returns an object with the relevant data
		/// </returns>
		object ExecuteScalar();

		/// <summary>
		/// Execute Query and setup the DataReader
		/// </summary>
		/// <remarks>
		/// This method is used to execute the specified SQL Query against the selected
		/// data source and populate the data reader
		/// </remarks>
		void ExecuteReader();

		/// <summary>
		/// Advance to next record in Data Reader
		/// </summary>
		/// <remarks>
		/// This method is used to advance to the next record in the data reader.
		/// </remarks>
		/// <returns>
		/// A boolean is reurned indicating the success of the method
		/// </returns>
		bool ReaderRead();

		/// <summary>
		/// Determine if the reader contains the specified field
		/// </summary>
		/// <param name="fieldName">Field name</param>
		/// <returns>
		/// A boolean value is returned indicating if the field contains a null value
		/// </returns>
		bool ReaderContainsField(string fieldName);

		/// <summary>
		/// Determine if field in reader is null
		/// </summary>
		/// <remarks>
		/// This method is used to determine whether the specified field in a data reader
		/// contains a null value or not
		/// </remarks>
		/// <param name="fieldName">Field name</param>
		/// <returns>
		/// A boolean value is returned indicating if the field contains a null value
		/// </returns>
		bool ReaderIsFieldNull(string fieldName);

		/// <summary>
		/// Retrieve value from the data reader
		/// </summary>
		/// <remarks>
		/// This method is used to retrieve a column value from the data reader object after
		/// a successful execution of the <ref>ExecuteReader</ref> method.
		/// </remarks>
		/// <param name="fieldName">Field Name</param>
		/// <param name="dbType">Database type</param>
		/// <returns>
		/// An object is returned that represents the value of the field specified
		/// </returns>
		object ReaderGetValue(string fieldName, DbType dbType);

		/// <summary>
		/// Retrieve int16 value from the data reader
		/// </summary>
		/// <remarks>
		/// This method is used to retrieve a column value from the data reader object after
		/// a successful execution of the <ref>ExecuteReader</ref> method.
		/// </remarks>
		/// <param name="fieldName">Field Name</param>
		/// <returns>
		/// An int is returned that represents the value of the field specified
		/// </returns>
		int ReaderGetInt16Value(string fieldName);

		/// <summary>
		/// Retrieve int32 value from the data reader
		/// </summary>
		/// <remarks>
		/// This method is used to retrieve a column value from the data reader object after
		/// a successful execution of the <ref>ExecuteReader</ref> method.
		/// </remarks>
		/// <param name="fieldName">Field Name</param>
		/// <returns>
		/// An int is returned that represents the value of the field specified
		/// </returns>
		int ReaderGetInt32Value(string fieldName);

		/// <summary>
		/// Retrieve Int64 value from the data reader
		/// </summary>
		/// <remarks>
		/// This method is used to retrieve a column value from the data reader object after
		/// a successful execution of the <ref>ExecuteReader</ref> method.
		/// </remarks>
		/// <param name="fieldName">Field Name</param>
		/// <returns>
		/// An int is returned that represents the value of the field specified
		/// </returns>
		long ReaderGetInt64Value(string fieldName);

		/// <summary>
		/// Retrieve double value from the data reader
		/// </summary>
		/// <remarks>
		/// This method is used to retrieve a column value from the data reader object after
		/// a successful execution of the <ref>ExecuteReader</ref> method.
		/// </remarks>
		/// <param name="fieldName">Field Name</param>
		/// <returns>
		/// A double is returned that represents the value of the field specified
		/// </returns>
		double ReaderGetDoubleValue(string fieldName);

		/// <summary>
		/// Clear Stored Procedure Parameters
		/// </summary>
		/// <remarks>
		/// This method is used to clear the stored procedure paramter list.
		/// </remarks>
		void ClearParameters();

		/// <summary>
		/// Add a new stored procedure parameter
		/// </summary>
		/// <remarks>
		/// This method is used to add a new stored procedure parameter that will be passed to the
		/// stored procedure on execution.
		/// </remarks>
		/// <param name="parameterName">Parameter Name</param>
		/// <param name="dbType">Parameter database type</param>
		/// <param name="parameterValue">Parameter value</param>
		void AddParameter(string parameterName, DbType dbType, object parameterValue);

		/// <summary>
		/// Add a new stored procedure parameter
		/// </summary>
		/// <remarks>
		/// This method is used to add a new stored procedure parameter that will be passed to the
		/// stored procedure on execution.
		/// </remarks>
		/// <param name="parameterName">Parameter Name</param>
		/// <param name="dbType">Parameter database type</param>
		/// <param name="parameterValue">Parameter value</param>
		/// <param name="parameterDirection">Parameter direction</param>
		void AddParameter(string parameterName, DbType dbType,
											object parameterValue, ParameterDirection parameterDirection);

		/// <summary>
		/// Add a new stored procedure parameter
		/// </summary>
		/// <remarks>
		/// This method is used to add a new stored procedure parameter that will be passed to the
		/// stored procedure on execution.
		/// </remarks>
		/// <param name="parameterName">Parameter Name</param>
		/// <param name="dbType">Parameter database type</param>
		/// <param name="parameterValue">Parameter value</param>
		/// <param name="parameterDirection">Parameter direction</param>
		void AddSqlParameter(string parameterName, SqlDbType dbType,
												 object parameterValue, ParameterDirection parameterDirection);
		
		/// <summary>
		/// Add a new stored procedure parameter
		/// </summary>
		/// <remarks>
		/// This method is used to add a new stored procedure parameter that will be passed to the
		/// stored procedure on execution.
		/// </remarks>
		/// <param name="parameterName">Parameter Name</param>
		/// <param name="parameterValue">Parameter value</param>
		void AddParameter(string parameterName, object parameterValue);

		/// <summary>
		/// Retrieve a specific parameter value
		/// </summary>
		/// <param name="parameterName">Name of the parameter</param>
		/// <returns>
		/// An object is returned that contains the value of the specified parameter.
		/// </returns>
		object GetParameterValue(string parameterName);
		#endregion
	}
}
